cciones
La abstracción realizada se centra especialmente en las acciones (procedimientos)
El modelo de programación orientado a objetos
Define el concepto de objeto
Un objeto es una abstracción que representa algo en la vida real
El objeto representa un estado (a través de atributos) y unos comportamientos (a través de métodos)
Así, es posible razonar en términos de objetos que encapsulan la complejidad
La abstracción, en este caso, se centra especialmente en los datos (objetos)
Ingeniería del software: orientación a objetos
La abstracción recurre frecuente al uso de diagramas de cajas y flechas para representar sistemas complejos de múltiples elementos que guardan relación
El problema es que las cajas y las flechas pueden significar cosas distintas para personas distintas, por lo que la comprensión de los diagramas se dificulta
UML (Unified Modeling Language): El un lenguaje que proporciona un conjunto de notaciones estándar para representar modelos abstractos de objetos
UML define un conjunto estandarizado de cajas y flechas con significados precisos que permiten representar objetos y algunas de sus relaciones
UML está limitado, es decir, hay modelos que se pueden representar mediante UML y hay modelos para los que UML no posee notación estandarizada
En esta asignatura, es conveniente conocer la notación de los diagramas de clases definidos en UML
UML es útil para representar (y documentar) la arquitectura de una aplicación
Siempre que utilicemos UML en los diagramas lo indicaremos de manera explícita
Ingeniería del software: UML
Diagramas de clases básicos en UML
Existen algunos términos que aparecen de manera recurrente en el ámbito de los ingenieros de trabajan en computación distribuida
Toolkits y frameworks
Los toolkits y frameworks suelen consistir en un conjunto de clases, herramientas, APIs, ejemplos de programación y documentación que algunos fabricantes distribuyen con el fin de facilitar el desarrollo de software distribuido
El éxito de una tecnología concreta depende en gran medida de la calidad de las herramientas que se proporcionan al desarrollador en el correspondiente toolkit
Ejemplos de toolkits y frameworks
JDK (Java Development Toolkit): Distribuido de manera gratuita por Sun Microsystems para desarrolladores interesados en el lenguaje Java
.NET framework: Distribuido por Microsoft para desarrolladores Web en sistema operativo Windows.
Ingeniería del Software: algo de terminología
Componentes
El desarrollo de software basado en componentes es una técnica muy habitual para la construcción de sistemas software distribuidos empresariales
Los componentes son unidades funcionales independientes accesibles de manera distribuida
Un sistema software distribuido se puede construir mediante la unión de componentes preexistentes y bien probados
De este modo se minimiza el tiempo y los costes de desarrollo
Para que esta filosofía tenga sentido, los componentes deben poder cooperar a través de una red abierta
Es necesario definir mecanismos estándar que posibiliten las interacciones entre componentes que, en principio, pueden ser heterogéneos
El desarrollo basado en componentes también es un intento de minimizar la complejidad
Ejemplos de estándares para el desarrollo de componentes utilizados en la industria
EJB (Enterprise Java Beans): Estándar para el desarrollo de componentes distribuidos basado en tecnologías Java
COM (Component Object Model): Estándar para el desarrollo de componentes distribuidos basado en tecnologías Microsoft
Ingeniería del Software: algo de terminología
1.1: Definiciones y conceptos básicos
1.2: Algunas nociones (muy) básicas sobre Java
1.3: Disciplinas base de la computación distribuida
1.4: IPC (Inter Process Communications): Comunicación entre procesos
1.5: Paradigmas de la computación distribuida
Lección 1.4
Los servicios de comunicación entre procesos son la base de los sistemas distribuidos al permitir que dos procesos colaboren para lograr una tarea
Hay dos mecanismos básicos de comunicación entre procesos
1- Comunicación entre procesos a nivel del sistema operativo (sin red)
Permiten la comunicación entre dos procesos en el mismo ordenador
Ejemplos: Colas de mensajes, semáforos, memoria compartida, etc.
No vamos a utilizarlos en este curso
2- Comunicación entre procesos a través de una red
Permiten la comunicación entre dos procesos que residan en la misma red
En este caso, la comunicación se produce a través del intercambio de mensajes entre un emisor y un receptor
El intercambio puede ser uno-a-uno (unicast unidifusión) o uno-a-grupo (multicast multidifusión)
IPC Comunicación entre procesos
Cuando un ordenador tiene soporte de red, ofrece una API que proporciona los servicios de comunicaciones
Estas APIs tratan de proporcionar una interfaz abstracta al programador
Toda API debe proporcionar, al menos, cuatro tipos de operaciones al desarrollador
ENVIAR: Es una primitiva que invoca el proceso emisor con el propósito de transmitir datos a un proceso receptor. Esta primitiva debe permitir identificar al proceso receptor así como especificar los datos a transmitir
RECIBIR: Es una primitiva que invoca el proceso receptor con el objetivo de aceptar datos de un proceso emisor. Debe permitir identificar al proceso receptor así como especificar el área de memoria en la que se almacenará la información recibida
Inicio de la conexión: Para mecanismos de comunicación orientados a conexión, deben existir primitas que permitan que la conexión se establezca. Lo habitual es que existan dos de ellas:
ESPERAR-CONEXIÓN: Es una primitiva invocada por un proceso que está dispuesto a recibir la conexión de otro proceso de forma pasiva.
INICIAR-CONEXIÓN: Esta primitiva es invocada por un proceso que quiere iniciar una conexión de manera activa con otro proceso. Es necesario identificar al proceso remoto
DESCONECTAR: En comunicaciones orientadas a conexión, cualquiera de los dos extremos de una conexión establecida pueden liberarla invocando esta primitiva
Elementos básicos de una API de IPC para redes
Si observamos detenidamente la API básica que hemos definido vemos que
Para que un mensaje pueda transferirse realmente, necesitamos que
Toda llamada ENVIAR en un extremo, debe tener una llamada RECIBIR en el otro
Para que una conexión pueda establecerse realmente, necesitamos que
Toda llamada INICIAR-CONEXIÓN debe tener un ESPERAR-CONEXIÓN asociada
¿Cómo logran los procesos ponerse de acuerdo para coordinar sus llamadas?
Más aún
¿Qué tenemos que hacer cuando en el código que desarrollamos para que los programas se coordinen al ejecutarse como procesos?
Sincronización de los procesos remotos
Proceso E
Proceso R
ENVIAR
RECIBIR?
Proceso E
Proceso R
INICIAR
ESPERAR?
Definición de Sincronizar:
Hacer que coincidan en el tiempo dos o más fenómenos
¿Cómo sincronizamos la ejecución de ENVIAR en un proceso con la ejecución de RECIBIR en el otro?
El mecanismo de sincronización más sencillo es el de utilizar comandos bloqueantes
Un comando bloqueante es aquel que bloquea al proceso que lo invoca hasta que se verifica una cierta condición, momento en el que el proceso para a estar Listo
Para el envío de un mensaje, el primer proceso que alcanza el comando ENVIAR/RECIBIR se bloquea hasta que el otro proceso lo alcanza
Para el establecimiento de una conexión, el proceso que invoca ESPERAR se bloquea hasta que otro proceso invoca INICIAR
Sincronización de los procesos remotos
Ejemplo de comunicación con comandos bloqueantes
…
int x = leerDato();
int y = leerOtroDato();
int z = x + y;
String resultado=Suma=+z;
enviar(procesoII, resultado);
…
…
llamarYoda();
sacarEspadaLaser();
matarSauron();
int z = recibir(procesoI)
pagarImpuestos(z);
…
ProgramaII
ProgramaI
(Gp:) Listo
(Gp:) Bloqueado
(Gp:) Ejecutando
(Gp:) Listo
(Gp:) Bloqueado
(Gp:) Ejecutando
Ejecutando
Ejemplo de comunicación con comandos bloqueantes
…
int x = leerDato();
int y = leerOtroDato();
int z = x + y;
String resultado=Suma=+z;
enviar(procesoII, resultado);
…
…
llamarYoda();
sacarEspadaLaser();
matarSauron();
int z = recibir(procesoI)
pagarImpuestos(z);
…
ProgramaII
ProgramaI
(Gp:) Listo
Bloqueado
Ejecutando
(Gp:) Listo
Bloqueado
Ejecutando
Ejemplo de comunicación con comandos bloqueantes
…
int x = leerDato();
int y = leerOtroDato();
int z = x + y;
String resultado=Suma=+z;
enviar(procesoII, resultado);
…
…
llamarYoda();
sacarEspadaLaser();
matarSauron();
int z = recibir(procesoI)
pagarImpuestos(z);
…
ProgramaII
ProgramaI
(Gp:) Listo
Bloqueado
Ejecutando
(Gp:) Listo
Bloqueado
Ejecutando
Ejemplo de comunicación con comandos bloqueantes
…
int x = leerDato();
int y = leerOtroDato();
int z = x + y;
String resultado=Suma=+z;
enviar(procesoII, resultado);
…
…
llamarYoda();
sacarEspadaLaser();
matarSauron();
int z = recibir(procesoI)
pagarImpuestos(z);
…
ProgramaII
ProgramaI
(Gp:) Listo
Bloqueado
Ejecutando
(Gp:) Listo
Bloqueado
Ejecutando
Ejemplo de comunicación con comandos bloqueantes
…
int x = leerDato();
int y = leerOtroDato();
int z = x + y;
String resultado=Suma=+z;
enviar(procesoII, resultado);
…
…
llamarYoda();
sacarEspadaLaser();
matarSauron();
int z = recibir(procesoI)
pagarImpuestos(z);
…
ProgramaII
ProgramaI
(Gp:) Listo
Bloqueado
Ejecutando
(Gp:) Listo
Bloqueado
Ejecutando
Ejemplo de comunicación con comandos bloqueantes
…
int x = leerDato();
int y = leerOtroDato();
int z = x + y;
String resultado=Suma=+z;
enviar(procesoII, resultado);
…
…
llamarYoda();
sacarEspadaLaser();
matarSauron();
int z = recibir(procesoI)
pagarImpuestos(z);
…
ProgramaII
ProgramaI
(Gp:) Listo
Bloqueado
Ejecutando
(Gp:) Listo
Bloqueado
Ejecutando
Ejemplo de comunicación con comandos bloqueantes
…
int x = leerDato();
int y = leerOtroDato();
int z = x + y;
String resultado=Suma=+z;
enviar(procesoII, resultado);
…
…
llamarYoda();
sacarEspadaLaser();
matarSauron();
int z = recibir(procesoI)
pagarImpuestos(z);
…
ProgramaII
ProgramaI
(Gp:) Listo
Bloqueado
Ejecutando
(Gp:) Listo
Bloqueado
Ejecutando
Ejemplo de comunicación con comandos bloqueantes
…
int x = leerDato();
int y = leerOtroDato();
int z = x + y;
String resultado=Suma=+z;
enviar(procesoII, resultado);
…
…
llamarYoda();
sacarEspadaLaser();
matarSauron();
int z = recibir(procesoI)
pagarImpuestos(z);
…
ProgramaII
ProgramaI
(Gp:) Listo
Bloqueado
Ejecutando
(Gp:) Listo
Bloqueado
Ejecutando
Ejemplo de comunicación con comandos bloqueantes
…
int x = leerDato();
int y = leerOtroDato();
int z = x + y;
String resultado=Suma=+z;
enviar(procesoII, resultado);
…
…
llamarYoda();
sacarEspadaLaser();
matarSauron();
int z = recibir(procesoI)
pagarImpuestos(z);
…
ProgramaII
ProgramaI
(Gp:) Listo
Bloqueado
Ejecutando
(Gp:) Listo
Bloqueado
Ejecutando
Ejemplo de comunicación con comandos bloqueantes
…
int x = leerDato();
int y = leerOtroDato();
int z = x + y;
String resultado=Suma=+z;
enviar(procesoII, resultado);
…
…
llamarYoda();
sacarEspadaLaser();
matarSauron();
int z = recibir(procesoI)
pagarImpuestos(z);
…
ProgramaII
ProgramaI
(Gp:) Listo
Bloqueado
Ejecutando
(Gp:) Listo
Bloqueado
Ejecutando
Ejemplo de comunicación con comandos bloqueantes
…
int x = leerDato();
int y = leerOtroDato();
int z = x + y;
String resultado=Suma=+z;
enviar(procesoII, resultado);
…
…
llamarYoda();
sacarEspadaLaser();
matarSauron();
int z = recibir(procesoI)
pagarImpuestos(z);
…
ProgramaII
ProgramaI
(Gp:) Listo
Bloqueado
Ejecutando
(Gp:) Listo
Bloqueado
Ejecutando
Ejemplo de comunicación con comandos bloqueantes
…
int x = leerDato();
int y = leerOtroDato();
int z = x + y;
String resultado=Suma=+z;
enviar(procesoII, resultado);
…
…
llamarYoda();
sacarEspadaLaser();
matarSauron();
int z = recibir(procesoI)
pagarImpuestos(z);
…
ProgramaII
ProgramaI
(Gp:) Listo
Bloqueado
Ejecutando
(Gp:) Listo
Bloqueado
Mensaje
Ejecutando
Ejemplo de comunicación con comandos bloqueantes
…
int x = leerDato();
int y = leerOtroDato();
int z = x + y;
String resultado=Suma=+z;
enviar(procesoII, resultado);
…
…
llamarYoda();
sacarEspadaLaser();
matarSauron();
int z = recibir(procesoI)
pagarImpuestos(z);
…
ProgramaII
ProgramaI
Listo
Bloqueado
Ejecutando
(Gp:) Listo
Bloqueado
Mensaje
Ejecutando
Ejemplo de comunicación con comandos bloqueantes
…
int x = leerDato();
int y = leerOtroDato();
int z = x + y;
String resultado=Suma=+z;
enviar(procesoII, resultado);
…
…
llamarYoda();
sacarEspadaLaser();
matarSauron();
int z = recibir(procesoI)
pagarImpuestos(z);
…
ProgramaII
ProgramaI
Listo
Bloqueado
Ejecutando
(Gp:) Listo
Bloqueado
Mensaje
Las operaciones de IPC que bloquean al proceso llamante se llaman síncronas
Una operación bloqueante solo se desbloquea cuando sucede el evento esperado en el extremo remoto. Es decir, garantizamos que hay una sincronización
Existen multitud de APIs de IPC síncronas y es posible programar con ellas
Existen también APIs de IPC asíncronas, en las que las llamadas no se bloquean
En estos casos, es responsabilidad del programador lograr la sincronización
¿Por qué puede querer alguien llamadas asíncronas?
Para evitar bloqueos indefinidos
Para mejorar las prestaciones y no desperdiciar ciclos de reloj
Ejemplo: programa que recibe de muchas fuentes y almacena paquetes
while(true){
int resultado = recibir(paquete);
if(resultado == -1)
continue;
else
almacena(paquete);
}
El programador debe saber si trabaja con llamadas síncronas o asíncronas
Envío y recepción síncronas
Al desarrollar programas distribuidos, es necesario codificar tanto la parte receptora como la parte emisora ¿qué modelo hay que usar en cada caso?
La sincronía/asincronía de las llamadas depende del servicio subyacente
Para comprenderlo, necesitamos realizar diagramas de eventos
Llamadas síncronas y asíncronas
Evento
Tiempo
Periodo suspendido
Proceso E
Proceso R
Mensaje Obligatorio
El Proceso R (receptor) se bloquea al invocar RECIBIR
El Proceso E (emisor) se bloquea al invocar ENVIAR
El Proceso R puede continuar ejecutando cuando ha terminado de recibir el mensaje
El Proceso E requiere un acuse de recibo (ACK) confirmando una recepción correcta para poder desbloquearse
Enviar síncrono y recibir síncrono
Proceso E
Proceso R
ENVIAR
RECIBIR
Asentimiento
El asentimiento forma parte del protocolo que implementa el servicio ICP (es transparente para el programador)
El mecanismo enviar-síncrono/recibir-síncrono es aconsejable cuando la lógica de la aplicación de ambos procesos necesita que los datos enviados se reciban antes de continuar con el procesamiento
Este mecanismo es utilizado cuando el servicio IPC es de transporte fiable orientado a conexión (p.e. TCP)
La realidad puede ser un poco más complicada (bufferes intermedios de recepción, ACKs perdidos, etc)
El Proceso R (receptor) se bloquea al invocar RECIBIR
El Proceso E (emisor) no se bloquea al invocar ENVIAR
El Proceso E envía el mensaje y continúa sin esperar
El Proceso E no requiere un acuse de recibo (ACK) confirmando la recepción
Enviar asíncrono y recibir síncrono
Proceso E
Proceso R
ENVIAR
RECIBIR
Este esquema es apropiado cuando la lógica de la aplicación emisora no depende de la recepción de los datos en el otro extremo
Este esquema suele utilizarse cuando el mecanismo IPC subyacente no garantiza que los datos enviados sean, realmente, entregados al receptor (p.e. UDP)
El Proceso R (receptor) no se bloquea al invocar RECIBIR
El Proceso E (emisor) se bloquea al invocar ENVIAR
El Proceso E envía el mensaje y se bloquea
El Proceso E requiere un acuse de recibo (ACK) para desbloquearse
Hay 3 escenarios
Enviar síncrono y recibir asíncrono
Escenario 1
Los datos ya han llegado al Proceso R cuando se invoca RECIBIR
En este caso, los datos se entregan al Proceso R inmediatamente
Un ACK desbloquea al Proceso E
Proceso E
Proceso R
ENVIAR
RECIBIR
Asentimiento
Escenario 2
Cuando el Proceso R invoca RECIBIR, los datos no han llegado
El Proceso R no recoge ningún dato
Para evitar un bloqueo indefinido del Proceso E, es necesario invocar RECIBIR nuevamente
Enviar síncrono y recibir asíncrono Cont
En este tipo de escenario el receptor se programa como un bucle en el que, cada cierto tiempo, se chequea si hay nuevos datos recibidos
A esta técnica se le denomina polling
Cuando los datos son finalmente recibidos, el Proceso E puede desbloquearse
Proceso E
Proceso R
ENVIAR
RECIBIR
Asentimiento
RECIBIR
RECIBIR
Escenario 3
Cuando el Proceso R invoca RECIBIR, los datos no han llegado
El Proceso R no recoge ningún dato
Para evitar un bloqueo indefinido del Proceso E, se eleva un evento en el Proceso R cuando los datos realmente se reciben
Enviar síncrono y recibir asíncrono Cont.
Este evento tiene asociado un manejador, que ejecuta la recepción real de los datos
El manejador es un método (función) que se invoca en el momento de la recepción, normalmente en un hilo diferente
Para que este esquema funcione, el mecanismo IPC debe implementar el servio de evento con retrollamada
Los tres escenarios se pueden usar cuando se requiere un transporte fiable de los datos (p.e. TCP) y, al mismo tiempo, se requiere que el receptor no se bloquee
Proceso E
Proceso R
ENVIAR
RECIBIR
Asentimiento
Evento
Ninguno de los dos procesos se bloquea
Este mecanismo sólo tiene sentido cuando no se requiere un transporte fiable y, además, se usa un mecanismo de eventos con retrollamadas
Este esquema no es muy utilizado
Enviar asíncrono y recibir asíncrono
Proceso E
Proceso R
ENVIAR
RECIBIR
Evento
Ventaja clara: facilita la vida del programador a la hora de sincronizar los procesos
Inconvenientes:
Puede producir bloqueos indefinidos de un proceso (p.e. RECIBIR sin ENVIAR)
Puede producir interbloqueos (p.e. los dos extremos llaman a RECIBIR)
Es inaceptable cuando se requieren altas prestaciones (p.e. servidores)
Dos estrategias para minimizar los inconvenientes de llamadas síncronas
Estrategia I: Temporizadores
La mayoría de las APIs de IPC de red permiten el uso de temporizadores (timeouts) que se pueden utilizar para fijar el tiempo máximo de bloqueo
Ejemplo: RECIBIR(procesoRemoto, bufferDatos, 3000)
Revisión crítica del mecanismo de bloqueo
RECIBIR
timeout
Recepcion
correcta
Continúa el
programa
Código error o
excepción
Estrategia II: Uso de múltiples hilos de ejecución
Esta estrategia se utiliza habitualmente para el desarrollo de servidores
Consiste en crear hilos específicos para algunas operaciones bloqueantes
La operación bloqueante, sólo detiene su propio hilo sin afectar al resto
Este tipo de estrategia suele requerir el uso de control de concurrencia
Revisión crítica del mecanismo de bloqueo Cont.
Proceso
Nuevo hilo
RECIBIR
Nuevo hilo
ENVIAR
1.1: Definiciones y conceptos básicos
1.2: Algunas nociones (muy) básicas sobre Java
1.3: Disciplinas base de la computación distribuida
1.4: IPC (Inter Process Communications): Comunicación entre procesos
1.5: Paradigmas de la computación distribuida
Lección 1.5
Definición de Paradigma:
Patrón, ejemplo o modelo
Estilo o conjunto de prácticas utilizadas para desarrollar un programa (software)
Es decir, identificar los paradigmas de la computación distribuida es identificar los modelos, patrones y prácticas que se utilizan habitualmente para desarrollar programas que funcionan en un sistema distribuido
En computación distribuida existen centenares de paradigmas, vamos a identificar los más habituales y populares ordenándolos según su nivel de abstracción
Paradigmas de computación distribuida
Hardware
Cliente–servidor, peer-to-peer
RPC y RMI
Servicios de red, ORB
Espacios de objetos, aplicaciones colaborativas
Modelo OSI, modelo TCP/IP
Paso de mensajes
Nivel de abstracción creciente
Estudiado en
cursos anteriores
Estudiado en
este curso
No se ve en este
curso
El paradigma de paso de mensajes es una abstracción para lograr IPC
¿Qué simplifica esta abstracción?
Abstrae todas las complejidades del modelo en capas (es decir, de la red)
Servicio con primitivas ENVIAR, RECIBIR, ESPERAR-CONEXIÓN, INICIAR-CONEXIÓN
Se logra que la E/S por red sea similar a la E/S típica de ficheros
¿Qué restringe esta abstracción?
Hace invisibles (e intocables) los detalles de las capas inferiores (¿Qué pasa si quiero crear un paquete IP falsificando la dirección de origen?)
Ejemplo de implementación
La API Sockets implementa este modelo
Paradigma de paso de mensajes
Proceso E
Proceso R
Mensaje I
Mensaje II
El paradigma cliente servidor es esencialmente un patrón arquitectural
También es una abstracción sobre el modelo de paso de mensajes
Se basa en establecer roles asimétricos a los procesos que colaboran
Un proceso es el Servidor:
Espera de manera pasiva peticiones de los clientes
Responde a esas peticiones según un servicio predefinido
Otro proceso es el Cliente (puede haber varios):
Invoca peticiones al servidor
Espera la respuesta de los clientes
¿Qué simplifica esta abstracción?
Simplifica la sincronización en los procesos (se sabe quién espera y actúa)
Simplifica la implementación de servicios compartidos por múltiples clientes
¿Qué restringe esta abstracción?
Establece a priori el papel de cada proceso (¿Qué sucede si quiero que un cliente se convierta en servidor?)
Ejemplos de implementación
La mayoría de las aplicaciones más populares en Internet (HTTP, FTP, DNS, etc.)
El mecanismo de servlets de Java está concebido para implementar servidores
Paradigma cliente-servidor
El paradigma peer-to-peer es un patrón arquitectural
No ofrece una abstracción notable con respecto al modelo de paso de mensajes
Elimina la asimetría del modelo cliente-servidor
Todos los procesos son equivalentes desde el punto de vista de su habilidad para solicitar o proveer servicios a otros procesos
Lo que simplifica y restringe este paradigma es muy dependiente de las facilidades que soporten las APIs que se utilicen para el desarrollo
La comunicación suele basarse en mecanismos de petición-respuesta síncronos similar al del modelo cliente-servidor
Ejemplos de implementación
Todo tipo de aplicaciones de mensajería instantánea, intercambio de ficheros, vídeo-conferencia, etc.
El proyecto JXTA o el proyecto Jabber ofrecen APIs y estándares para el desarrollo de sistemas basados en el paradigma peer-to-peer
Paradigma peer-to-peer (igual-a-igual)
P1
P2
P3
MOM (Message Oriented Middleware): Middleware Orientado a Mensajes
Patrón arquitectural + abstracción similar a la del modelo cliente-servidor
Middleware: un software que está en medio
El modelo MOM propone la introducción de un middlerware que actúa de intermediario entre un sistema proveedor de servicios (servidor) y un sistema consumidor de servicios (cliente) desacoplándolos
El emisor (cliente) deposita una petición en el sistema de gestión de mensajes
El emisor queda libre para seguir con sus tareas
El sistema de gestión de mensajes actúa como un conmutador dirigiendo la petición hacia el receptor (servidor) más apropiado para procesarla
Los receptores almacenan las peticiones en una cola y las van procesando de manera asíncrona siguiendo una política predefinida (FIFO, LIFO, etc.)
Cuando una petición se procesa, la respuesta es entregada al proceso emisor (quizás con la intermediación del sistema de mensajes)
El proceso emisor puede recuperar la respuesta utilizando polling o a través de un mecanismo de retrollamadas
Paradigma MOM
¿Qué simplifica esta abstracción?
Proporciona una abstracción adicional para operaciones asíncronas con respecto al modelo de paso de mensajes que simplifica su desarrollo y comprensión
Permite desacoplar el emisor del receptor (mejora manteniblidad)
¿Qué restringe esta abstracción?
El modelo asíncrono elimina cualquier tipo de control que se pueda tener sobre las temporizaciones y la sincronización del emisor y el receptor
Ejemplos de implementación
Microsoft Message Queue (MSMQ), Java Message Service (JMS), etc.
Paradigma MOM Cont.
MOM
Emisor
Emisor
Emisor
Receptor
Receptor
Es paradigma de publicación/suscripción es un patrón arquitectural
También es una abstracción sobre el modelo de paso de mensajes
Como en el modelo cliente-servidor, hay dos roles asimétricos
El publisher (editor)
Recibe o produce eventos de diferentes tipos
Los subscritores (subscribers)
Se suscriben a eventos de determinado tipo
Cuando en el servidor se produce un evento, todos los suscriptores que hayan declarado su interés por ese tipo de evento son informados a través del envío de un mensaje, que contiene la información relevante sobre el evento
El modelo de programación del suscriptor está basado en retrollamadas
Este esquema se utiliza también para el desarrollo de aplicaciones monolíticas (p.e. en desarrollo de interfaces de usuario)
Paradigma de publicación/suscripción
¿Qué simplifica esta abstracción?
Facilita la implementación de servicios de multidifusión
Facilita el desarrollo de aplicaciones que gestionan eventos asíncronos (pe. control)
¿Qué restringe esta abstracción?
El propio modelo restringe el ámbito de aplicación
Ejemplos de implementación
Paradigma de publicación/suscripción
Publisher
Suscriptor
Suscriptor
Suscriptor
Evento
Evento
Suscripciones
Publicación de eventos
Evento
RPC (Remote Procedure Call): Llamadas a procedimientos remotos
Es una abstracción notable sobre todos los modelos basados en paso de mensajes
No es un patrón arquitectural
La idea es la de lograr que, desde el punto de vista del programador, el desarrollo de aplicaciones distribuidas sea idéntico al desarrollo de aplicaciones monolíticas
Es decir, la idea es la de ofrecer abstracciones que eliminen todo lo que tenga que ver con comunicaciones, redes, mensajes, protocolos, etc.
Las RPC se basa en el mimetismo del modelo de programación procedimental
Existe un modelo análogo que mimetiza la filosofía orientada a objetos: el RMI
¿Qué simplifica este paradigma?
Permite que desarrollar aplicaciones distribuidas sea tan fácil como desarrollar aplicaciones monolíticas (
lo matizaremos)
El desarrollador no tiene por qué saber nada de protocolos, mensajes, formatos
¿Qué restringe este paradigma?
Hace invisibles (e intocables) todo lo que tiene que ver con protocolos, mensajes, formatos, etc. (¿Qué pasa si quiero saber si un mensaje se ha recibido duplicado?, ¿si quiero comprimir los datos de un mensaje?¿si quiero ralentizar el envío de mensajes?, etc.
Está adaptado para comportamientos síncronos (petición-respuesta bloqueante)
Ejemplos de implementación
Java RMI, Sun RPC, DCE, etc.
Paradigmas RPC y RMI
Paradigmas RPC y RMI Cont.
…
int x = 10
int y = 20
int z = sumar(x+y)
…
int sumar(int a, int b){
return a + b
}
Ejecución de llamada
monolítica
…
int x = 10
int y = 20
int z = sumar(x+y)
…
int sumar(int a, int b){
return a + b
}
Ejecución de llamada RPC
Mensaje
Mensaje
Proceso
Proceso
Proceso
Es una extensión del modelo RPC-RMI en la que se predefinen ciertos servicios
Los proveedores de servicios se registran en un directorio en tiempo de ejecución
Los consumidores pueden localizar los servicios consultando el directorio
La estandarización es imprescindible para lograr interoperabilidad
¿Qué simplifica este paradigma?
Permite mejorar la interoperabilidad
Simplifica el problema de la localización del interlocutor
Incentiva el uso directo de servicios estandarizados
¿Qué restringe este paradigma?
Requiere mecanismos de definición de interfaces
Restricciones similares a las del modelo RPC-RMI
Depende del a implementación
Ejemplos de implementación
La tecnología Jini de Java se basa en este modelo
Los Web Services (Servicios Web) se basan en este modelo
Paradigma de servicios de red
ORB (Object Request Broker): Intermediario de peticiones a objetos
El paradigma ORB es esencialmente un patrón arquitectural sobre el modelo RMI
Se añaden también funcionalidades adicionales que abstraen ciertos servicios
El ORB es un middleware que actúa como mediador en la petición a un objeto
El ORB puede realizar multitud de labores entre las que se incluyen:
Mediación entre objetos heterogéneos
Localización de objetos
Creación y activación de objetos bajo demanda
Etc.
Este paradigma es la base de la arquitectura CORBA
¿Qué simplifica este paradigma?
Al leer el estándar CORBA uno diría que este paradigma no simplifica nada
la realidad es que se elimina gran parte del trabajo tedioso, permitiendo que el desarrollador se centre en la lógica de negocio. Próximo a la filosofía orientada a componentes (el contenedor ofrece los servicios, el desarrollador la log. de negocio)
Mejora enormemente la interoperabilidad de las aplicaciones
¿Qué restringe este paradigma?
En general, las restricciones son similares a las del modelo RMI
Implementaciones concretas pueden añadir restricciones adicionales
Ejemplos de implementaciones
Cualquier implementación de un ORB CORBA (Orbix, TidORB, OpenORB, etc.)
Paradigma basado en ORB
Paradigma basado en ORB
Tema I: Comentarios y referencias
Comentarios y reflexiones
¿Por qué la utilización de un patrón arquitectural en una aplicación distribuida restringe las capacidades de la aplicación?
Intenta imaginar qué tipo de mecanismo puede transformar una llamada a un procedimiento local (a un proceso) en una ejecución de un procedimiento remoto (en otro proceso). ¿Requiere este mecanismo el intercambio de mensajes?
¿Por qué crees que hay tantas abstracciones, patrones arquitecturales, toolkits, frameworks y APIs en el ámbito del desarrollo de aplicaciones distribuidas?
La compilación JIT del bytecode de Java ha mejorado las prestaciones de los programas escritos en este lenguaje. ¿Puedes encontrar información relativa al respecto?
Referencias
M.L. Liu, Computación Distribuida: Fundamentos y Aplicaciones, Pearson Addison Wesley, 2004. Capítulos 1,2 y 3
Bruce Eckel, Piensa en Java, Prentice Hall, 2003
Nunca desprecies el poder Wikipedia (www.wikipedia.org)
Tema I: Resumen
Contenidos
Computación Distribuida: Conceptos básicos
Definición
Ventajas/Inconvenientes
Falacias de la Computación Distribuida
Rudimentos de programación en Java
Disciplinas relacionadas con la computación distribuida
Sistemas operativos:
Procesos
Programación Concurrente
Ingeniería del software
Abstracción
Comunicación entre procesos (IPC)
Invocaciones bloqueantes/no-bloqueantes
Envío y recepción síncronos y asíncronos
Paradigmas de la computación distribuida
Paso de mensajes
Cliente/Servidor, P2P
RPC-RMI
ORB
Página anterior | Volver al principio del trabajo | Página siguiente |